/*****************************************************************************
 *  CommLayerLib - ConfigValue.java
 *  Copyright (C) 2012  Matteo Piscitelli
 *  E-mail: matteo@picciux.it
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  For further info, check http://code.google.com/p/java-comm-layer/
 *
 *  SVN: $Id: ConfigValue.java 23 2012-10-02 16:59:05Z picciux@gmail.com $
 *  
 *****************************************************************************/

package it.picciux.commlayer;

public class ConfigValue {
	private String key;
	private double dValue;
	private int iValue;
	private boolean bValue;
	private String sValue;
	private int valueType;

	public static final int VALUETYPE_STRING = 0;	
	public static final int VALUETYPE_INT = 1;	
	public static final int VALUETYPE_DOUBLE = 2;	
	public static final int VALUETYPE_BOOLEAN = 3;	
	public static final int VALUETYPE_ENUM = 4;  	
	
	public static final String KEYVALSEP = "=";
	public static final String LINESEP = "\r\n";
	
	
	/* constructors */
	public ConfigValue() {
		valueType = -1;
	}
	
	public ConfigValue(String key) {
		this.key = key;
		valueType = -1; // value not set
	}

	public ConfigValue(String key, String value) {
		this.key = key;
		setValue(value);
	}
	
	public ConfigValue(String key, int value) {
		this.key = key;
		setValue(value);
	}

	public ConfigValue(String key, double value) {
		this.key = key;
		setValue(value);
	}

	public ConfigValue(String key, boolean value) {
		this.key = key;
		setValue(value);
	}
	
	public String getKey() {
		if (valueType > -1)
			return key;
		else
			return "";
	}
	
	public void setValue(String value) {
		sValue = value;
		valueType = VALUETYPE_STRING;
	}

	public void setValue(int value) {
		iValue = value;
		sValue = writeInt(value);
		valueType = VALUETYPE_INT;
	}

	public void setValue(double value) {
		dValue = value;
		sValue = writeDouble(value);
		valueType = VALUETYPE_DOUBLE;
	}

	public void setValue(boolean value) {
		bValue = value;
		sValue = writeBoolean(value);
		valueType = VALUETYPE_BOOLEAN;
	}

	public static String keyValueGetKey(String s) {
		int i = s.indexOf(KEYVALSEP);
		if (i < 1) return "";
		
		return s.substring(0, i);
	}
	
	public static String keyValueGetValue(String s) {
		int i = s.indexOf(KEYVALSEP);
		if (i < 1) return "";
		
		return s.substring(i + 1);
	}

	public static String keyValueGetValueString(String s) {
		return keyValueGetValue(s);
	}
	
	public static int keyValueGetValueInt(String s) {
		return readInt(keyValueGetValue(s));
	}

	public static double keyValueGetValueDouble(String s) {
		return readDouble(keyValueGetValue(s));
	}
	
	public static boolean keyValueGetValueBoolean(String s) {
		return readBoolean(keyValueGetValue(s));
	}
	
	
	public String getValueString() {
		valueType = VALUETYPE_STRING;
		return sValue;
	}
	
	public int getValueInt() {
		if (valueType != VALUETYPE_INT) {
			valueType = VALUETYPE_INT;
			iValue = readInt(sValue);
		}
		return iValue;
	}

	public double getValueDouble() {
		if (valueType != VALUETYPE_DOUBLE) {
			valueType = VALUETYPE_DOUBLE;
			dValue = readDouble(sValue);
		}
		return dValue;
	}
	
	public boolean getValueBoolean() {
		if (valueType != VALUETYPE_BOOLEAN) {
			valueType = VALUETYPE_BOOLEAN;
			bValue = readBoolean(sValue);
		}
		return bValue;
	}
	
	public Object getValue() {
		switch(valueType) {
			case VALUETYPE_STRING:
				return sValue;
			case VALUETYPE_INT:
				return new Integer(iValue);
			case VALUETYPE_DOUBLE:
				return new Double(dValue);
			case VALUETYPE_BOOLEAN:
				return new Boolean(bValue);
			default:
				return null;
		}		
	}
	
	public String getString() {
		String ret = key + KEYVALSEP;
		
		switch(valueType) {
			case VALUETYPE_STRING:
				return ret + sValue;
			case VALUETYPE_INT:
				return ret + writeInt(iValue);
			case VALUETYPE_DOUBLE:
				return ret + writeDouble(dValue);
			case VALUETYPE_BOOLEAN:
				return ret + writeBoolean(bValue);
			default:
				return "";
		}
	}
	
	public boolean parseString(String s) {	
		key = keyValueGetKey(s);
		if (key == "") return false;
		sValue = keyValueGetValue(s);
		valueType = VALUETYPE_STRING;
		return true;
	}
	
	public boolean parseString(String s, int type) {
		if (!parseString(s)) return false;
		
		switch(type) {
			case VALUETYPE_STRING:
				break;
			case VALUETYPE_INT:
				iValue = readInt(sValue);
				break;
			case VALUETYPE_DOUBLE:
				dValue = readDouble(sValue);
				break;
			case VALUETYPE_BOOLEAN:
				bValue = readBoolean(sValue);
				break;
			default:
				return false;			
		}
		
		valueType = type;		
		return true;
	}
	
	/**
	 * Converts and integer to string
	 * @param i integer
	 * @return string of integer i
	 */
	public static String writeInt(int i) {
		return Integer.toString(i);
	}

	/**
	 * Converts and integer to string, zero-padding it 
	 * to reach len length
	 * @param i integer
	 * @param len integer
	 * @return zero-padded string of integer i
	 */
	public static String writePaddedInt(int i, int len) {
		String s = Integer.toString(i);
		
		int d = len - s.length();
		if (d <= 0) return s;
		
		for (int j = 0; j < d; j++)
			s = "0" + s;
		
		return s;
	}
	
	
	/**
	 * Converts a double to string
	 * @param d double
	 * @return string of double d
	 */
	public static String writeDouble(double d) {
		return Double.toString(d);
	}
	
	/**
	 * Converts a boolean to string
	 * @param b boolean
	 * @return string of boolean b
	 */
	public static String writeBoolean(boolean b) {
		if (b)
			return "true";
		else
			return "false";
	}
	
	/**
	 * Converts an integer to string
	 * @param i integer
	 * @return string of i
	 */
	public static String writeValue(int i) {
		return writeInt(i);
	}

	/**
	 * Converts a double to string
	 * @param d double
	 * @return string of double d
	 */
	public static String writeValue(double d) {
		return writeDouble(d);
	}

	/**
	 * Converts a boolean to string
	 * @param b boolean
	 * @return string of boolean b
	 */
	public static String writeValue(boolean b) {
		return writeBoolean(b);
	}

	public static String writeValue(String s) {
		return s;
	}
	
	// utils: conversion from string
	public static int readInt(String s) {
		try {
			return Integer.parseInt(s);
		} catch (Exception e) {
			return 0;
		}
	}

	public static double readDouble(String s) {
		try {
			return Double.parseDouble(s);
		} catch (Exception e) {
			return 0.0d;
		}
	}

	public static boolean readBoolean(String s) {
		if (s.equalsIgnoreCase("true"))
			return true;
		else
			return false;
		/*try {
			return Boolean.parseBoolean(s);
		} catch (Exception e) {
			return false;
		}*/
	}
	
	public static String writeKeyValue(String key, String value) {
		return key + KEYVALSEP + value;
	}
	
	public static String writeKeyValue(String key, int value) {
		return writeKeyValue(key, Integer.toString(value));
	}
	
	public static String writeKeyValue(String key, double value) {
		return writeKeyValue(key, Double.toString(value));
	}
	
	public static String writeKeyValue(String key, boolean value) {
		return writeKeyValue(key, writeBoolean(value));
	}
	

	
	
}
